<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script type="text/javascript">
      /* 
        在JavaScript中，我们创建一个函数A(就是声明一个函数), 
        那么浏览器就会在内存中创建一个对象B，
        而且每个函数都默认会有一个属性 prototype 指向了这个对象( 即：prototype的属性的值是这个对象 )。
        这个对象B就是函数A的原型对象，简称函数的原型。
        这个原型对象B 默认会有一个属性 constructor 指向了这个函数A ( 意思就是说：constructor属性的值是函数A )。
      */

      /* 
        原型 prototype

          在我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype
            这个属性对应着一个对象,这个对象就是原型对象,prototype保存这个原型对象的地址
          如果函数作为普通函数调用prototype没有任何作用
          当函数通过构造函数调用时,它所创建的对象中都会有一个隐含的属性
            指向该构造函数的原型对象,我们可以通过__proto__来访问属性

        
          原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问这个对象
            我们可以将对象中共有的内容,统一设置到原型对象中
          
          当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果自身对象有,则直接使用,
            如果没有则会去原型对象中寻找,如果找到则直接使用

          同时,将数据存储到原型对象中,不会污染到全局作用域,因为都是在原型对象里面
      */
      function Person() {}

      function MyClass() {}
      console.log(MyClass.prototype);

      console.log(MyClass.prototype == Person.prototype);

      //向MyClass的原型中添加属性a
      MyClass.prototype.a = 123;

      //向MyClass的原型中添加一个方法
      MyClass.prototype.sayHello = function () {
        alert('hello');
      };

      var mc = new MyClass();

      var mc2 = new MyClass();

      //向mc中添加a属性
      mc.a = '我是mc中的a';

      console.log(mc.__proto__ == MyClass.prototype); //true
      console.log(mc2.__proto__ == MyClass.prototype); //true

      console.log(mc2.a);

      mc.sayHello();
    </script>
  </head>
  <body></body>
</html>
